﻿
namespace System.Erp.Runtime
{
    /// <summary>
    /// 常量字符串，用于减少字符串的内存消耗和比较成本。
    /// </summary>
    /// <typeparam name="T">指向自己的类型。</typeparam>
    [Serializable]
    public abstract class ConstString<T> where T : ConstString<T>
    {
        private readonly string _strValue;
        private readonly int _hashcode;

        /// <summary>
        /// 派生类创建实例
        /// </summary>
        /// <param name="stringValue">常量字符串的值。</param>
        protected ConstString(string stringValue)
        {
            if (stringValue == null)
            {
                throw new ArgumentNullException("stringValue");
            }

            _strValue = stringValue;
            _hashcode = stringValue.GetHashCode();
        }

        /// <summary>
        /// 返回字符串描述
        /// </summary>
        /// <returns>此常量字符串的值。</returns>
        public override string ToString()
        {
            return _strValue;
        }

        /// <summary>
        /// 自定义的相等判断
        /// </summary>
        /// <param name="obj">要判断相等的对象</param>
        /// <returns>返回是否相等。</returns>
        public override bool Equals(object obj)
        {
            T other = obj as T;
            return (other == null) ? false : Equals(this, other);
        }

        /// <summary>
        /// 返回两个常量字符串是否相等
        /// </summary>
        /// <param name="a">要判断的对象</param>
        /// <param name="b">要判断的对象</param>
        /// <returns>如果对象相等返回true，否则返回false</returns>
        public static bool Equals(T a, T b)
        {
            return (object.ReferenceEquals(a,b) || 
                ((!object.ReferenceEquals(a,null) && !object.ReferenceEquals(b,null)) && 
                 (a._strValue == b._strValue)));
        }

        /// <summary>
        /// 返回此对象的Hashcode，为类型字符串的hashcode.
        /// </summary>
        /// <returns>Hashcode的值。</returns>
        public override int GetHashCode()
        {
            return _hashcode;
        }

        /// <summary>
        /// 返回此常量字符串的字符串表示形式。
        /// </summary>
        public string StringValue
        {
            get { return _strValue; }
        }
    }
}
